package top.buaarobot.webserver.web.rest;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import top.buaarobot.webserver.config.LimitParams;
import top.buaarobot.webserver.config.PathParams;
import java.io.IOException;
import java.lang.String;


import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Random;

@RestController
@RequestMapping("/api")
public class StreamResource {

    private static Long uploadPictureMaxSize = LimitParams.uploadPictureMaxSize;
    private static Long uploadDocumentMaxSize = LimitParams.uploadDocumentMaxSize;
    private static String docPath = PathParams.BasePath + PathParams.DocDir;
    private static String picPath = PathParams.BasePath + PathParams.PicDir;
    public String mediaPath = PathParams.BasePath + PathParams.MediaDir;
    private static char[] abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray();

    /*** Picture Upload
     * @throws JSONException ***/
    @RequestMapping(value = "/picture/upload",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            consumes="multipart/form-data")
    public @ResponseBody
    JSONObject uploadPictureOperation(
            @RequestParam("DefaultFileUploadFileInput") MultipartFile[] files)
            throws IllegalStateException, IOException, JSONException {
        JSONObject response = new JSONObject();
        //check file size , if too big , return fail status.
        Long fileSize = new Long(0);
        for (MultipartFile file : files) {
            fileSize += file.getSize();
        }
        if(fileSize > uploadPictureMaxSize){
            response.put("status","fail");
            return response;
        }else{
            response.put("status","ok");
        }

        String prefix = generateRandomPrefix(12);
        String Filename = prefix + files[0].getOriginalFilename();
        response.put("filename",Filename);
        File saveDir = new File(picPath);
        if(!saveDir.exists())
        {
            saveDir.mkdirs();
        }
        //save file to local memeroy.
        for (MultipartFile file : files) {
            File f= new File(picPath, Filename);
            try {
                file.transferTo(f);
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
        return new JSONObject(response);
    }

    /*** Documents Upload
     * @throws JSONException ***/
    @RequestMapping(value = "/document/upload",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            consumes="multipart/form-data")
    public @ResponseBody
    JSONObject uploadDocumentOperation(
            @RequestParam("DefaultFileUploadFileInput") MultipartFile[] files) throws IllegalStateException, IOException, JSONException {
        JSONObject response = new JSONObject();
        //check file size , if too big , return fail status.
        Long fileSize = new Long(0);
        for (MultipartFile file : files) {
            fileSize += file.getSize();
        }
        if(fileSize > uploadDocumentMaxSize){
            response.put("status","fail");
            return response;
        }else{
            response.put("status","ok");
        }

        String prefix = generateRandomPrefix(12);
        String Filename = prefix + files[0].getOriginalFilename();
        response.put("filename",Filename);
        File saveDir = new File(docPath);
        if(!saveDir.exists())
        {
            saveDir.mkdirs();
        }
        for (MultipartFile file : files) {
            File f= new File(docPath, Filename);
            try {
                file.transferTo(f);
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
        return response;
    }


    /*** File Upload
     * @throws JSONException ***/
    @RequestMapping(value = "/video/UploadFiles/",
            method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_VALUE,
            consumes="multipart/form-data")
    public @ResponseBody
    ResponseEntity uploadFileOperation(
            @RequestParam("DefaultFileUploadFileInput") MultipartFile[] files) throws IllegalStateException, IOException, JSONException {
        String filePath = docPath;           //"xyz/Test FileUpload/";
        String Filename = files[0].getOriginalFilename();
        //check is the same filename already exsist.
        ArrayList<String> names = getFile(docPath,1);
        //System.out.println(names.toString());
        if(names.contains(Filename)){
            return ResponseEntity.badRequest().body("filename exsist.");
        }
        File saveDir = new File(filePath);
        if(!saveDir.exists())
        {
            saveDir.mkdirs();
        }
        for (MultipartFile file : files) {
            File f= new File(filePath, Filename);
            try {
                file.transferTo(f); //Transfer or Saving in local memory
            }catch (IOException e) {
                e.printStackTrace();
            }
            //System.out.println("do something in here");
        }
        return ResponseEntity.ok().build();
    }

    //列出文件夹下的所有文件名,用于检查重名.
    private static ArrayList<String> getFile(String path, int deep){
        // 获得指定文件对象
        File file = new File(path);
        // 获得该文件夹内的所有文件
        File[] array = file.listFiles();
        ArrayList<String> list = new ArrayList<String>();
        int n = 0;
        for(int i=0;i<array.length;i++)
        {
            if(array[i].isFile())//如果是文件
            {
                for (int j = 0; j < deep; j++)//输出前置空格
                    System.out.print(" ");
                // 只输出文件名字
                list.add(array[i].getName());
            }
        }
        return list;
    }


    /**
     *
     * @param names 文件下文件名的集合
	 * @param name 存入的文件名
	 * @param index 索引的开始位置
	 * @return 符合要求的文件名
	 */
    private static String checkFileName(ArrayList<String> names,String name,int index) {
        if(names.contains(name.substring(0,name.indexOf("."))+index+name.substring(name.indexOf("."),name.length()))) {
            name = checkFileName(names,name,index+1);
        } else {
            return name.substring(0,name.indexOf("."))+index+name.substring(name.indexOf("."),name.length());
        }
        return name;
    }



    @GetMapping(value = "/video/{videoName}")
    public StreamingResponseBody getSteamingFile(HttpServletResponse response, @PathVariable("videoName") String name) throws IOException {
        response.setContentType("video/mp4");
        response.setHeader("Content-Disposition", "inline; filename=\""+name+".mp4\"");
        InputStream inputStream = new FileInputStream(new File(mediaPath,name+".mp4"));
        return outputStream -> {
            int nRead;
            byte[] data = new byte[1024];
            while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                //System.out.println("Writing some bytes..");
                outputStream.write(data, 0, nRead);
            }
        };
    }

    @GetMapping(value = "/picture/{picname}")
    public StreamingResponseBody getSteamingPicture(HttpServletResponse response, @PathVariable("picname") String name) throws IOException {
        response.setContentType("image/*");
        response.setHeader("Content-Disposition", "inline; filename=\""+name);
        InputStream inputStream = new FileInputStream(new File(picPath,name));
        return outputStream -> {
            int nRead;
            byte[] data = new byte[1024];
            while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                //System.out.println("Writing some bytes..");
                outputStream.write(data, 0, nRead);
            }
        };
    }
    @GetMapping(value = "/document/{docname}")
    public StreamingResponseBody getSteamingDocument(HttpServletResponse response, @PathVariable("docname") String name) throws IOException {
        System.out.println("buenos test docname: " + name.substring(12));
        response.setContentType("application/*");
        response.setHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(name.substring(12),"UTF-8") );
        InputStream inputStream = new FileInputStream(new File(docPath,name));
        return outputStream -> {
            int nRead;
            byte[] data = new byte[1024];
            while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                //System.out.println("Writing some bytes..");
                outputStream.write(data, 0, nRead);
            }
        };
    }

   /* @GetMapping(value = "/duolundipan")
    public StreamingResponseBody getSteamingFile1(HttpServletResponse response) throws IOException {
        response.setContentType("video/mp4");
        response.setHeader("Content-Disposition", "inline; filename=\"duolundipan.mp4\"");
        InputStream inputStream = new FileInputStream(new File(mediaPath,"duolundipan.mp4"));
        return outputStream -> {
            int nRead;
            byte[] data = new byte[1024];
            while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
                //System.out.println("Writing some bytes..");
                outputStream.write(data, 0, nRead);
            }
        };
    }*/


   private String generateRandomPrefix(Integer length){
       String prefix = new String();
       Random rdm = new Random();
       for(int i=0;i<length;i++){
           prefix += abc[rdm.nextInt(abc.length)];
       }
       return prefix;
   }

}
